<template>
    <div>
        <!-- 触发按钮 -->
        <el-button link type="primary" @click="dialogVisible = true" :icon="Edit">编辑树形数据</el-button>

        <!-- 弹窗 -->
        <el-dialog v-model="dialogVisible" title="树形数据配置" width="600px" @close="resetTree">
            <el-tree :data="treeData" :props="defaultProps" node-key="id" accordion :expand-on-click-node="false">
                <template #default="{ data }">
                    <div class="tree-node">
                        <el-input v-model="data.label" placeholder="Label" size="small"
                            style="width: 120px; margin-right: 8px;" />
                        <el-input v-model="data.value" placeholder="Value" size="small"
                            style="width: 100px; margin-right: 8px;" />
                        <el-button link @click.stop="addChild(data)" :icon="Plus" type="primary" circle size="small" />
                        <el-button link @click.stop="removeNode(data)" :icon="Delete" type="danger" circle
                            size="small" />
                    </div>
                </template>
            </el-tree>

            <div style="margin-top: 10px;">
                <el-button link @click="addRoot" type="primary" plain :icon="Plus">新增根节点</el-button>
            </div>

            <template #footer>
                <el-button @click="dialogVisible = false">取消</el-button>
                <el-button type="primary" @click="saveTree">确认</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, watch, inject } from 'vue'
import { Plus, Delete, Edit } from '@element-plus/icons-vue'

const designer = inject('designer')

const props = defineProps({
    modelValue: {
        type: Array,
        default: () => []
    }
})

const emit = defineEmits(['update:modelValue'])

const dialogVisible = ref(false)
const treeData = ref([])

const defaultProps = {
    children: 'children',
    label: 'label'
}

// 初始时深拷贝原始值
const resetTree = () => {
    treeData.value = JSON.parse(JSON.stringify(props.modelValue))
}

// 打开弹窗时初始化
watch(dialogVisible, (val) => {
    if (val) resetTree()
})

const addRoot = () => {
    treeData.value.push({
        id: designer.generateUniqueId('', treeData.value),
        label: '',
        value: '',
        children: []
    })
}

const addChild = (node) => {
    node.children = node.children || []
    node.children.push({
        id: designer.generateUniqueId('', treeData.value),
        label: '',
        value: '',
        children: []
    })
}

const removeNode = (target) => {
    const remove = (list, id) => {
        for (let i = list.length - 1; i >= 0; i--) {
            if (list[i].id === id) {
                list.splice(i, 1)
                return true
            }
            if (list[i].children) {
                if (remove(list[i].children, id)) return true
            }
        }
        return false
    }
    remove(treeData.value, target.id)
}

const saveTree = () => {
    emit('update:modelValue', treeData.value)
    dialogVisible.value = false
}
</script>

<style scoped>
.tree-node {
    display: flex;
    align-items: center;
}
</style>